package view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import controller.RuntimeController;

public class RuntimeControlView extends JComponent implements ActionListener {
	private static final long serialVersionUID = -9102935773049352766L;

	private static final int STEPS_MIN = 0;
	private static final int STEPS_MAX = 120;
	private static final int STEPS_INIT = 60; // initial steps per minute

	private static final int MAJOR_TICK_SPACING = 20;
	private static final int MINOR_TICK_SPACING = 5;

	private RuntimeController runtimeController = RuntimeController
			.getInstance();

	private JButton rewind;
	private JButton rewindOneStep;
	private JButton pause;
	private JButton playOneStep;
	private JButton play;

	public RuntimeControlView() {
		ImageIcon rewindIcon = createImageIcon("../images/rewind24.png",
				"Rewind");
		ImageIcon rewindOneStepIcon = createImageIcon(
				"../images/rewindOneStep24.png", "Rewind one step");
		ImageIcon pauseIcon = createImageIcon("../images/pause24.png", "Pause");
		ImageIcon playOneStepIcon = createImageIcon(
				"../images/playOneStep24.png", "Play one step");
		ImageIcon playIcon = createImageIcon("../images/play24.png", "Play");

		rewind = new JButton(rewindIcon);
		rewindOneStep = new JButton(rewindOneStepIcon);
		pause = new JButton(pauseIcon);
		playOneStep = new JButton(playOneStepIcon);
		play = new JButton(playIcon);

		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		JComponent buttons = makeButtons();
		buttons.setAlignmentX(LEFT_ALIGNMENT);
		this.add(buttons);
		JComponent slider = makeSlider();
		slider.setAlignmentX(LEFT_ALIGNMENT);
		this.add(slider);
	}

	private JComponent makeButtons() {
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
		panel.add(rewind);
		panel.add(rewindOneStep);
		panel.add(pause);
		panel.add(playOneStep);
		panel.add(play);

		rewind.addActionListener(this);
		rewindOneStep.addActionListener(this);
		pause.addActionListener(this);
		playOneStep.addActionListener(this);
		play.addActionListener(this);

		return panel;
	}

	private JComponent makeSlider() {
		JSlider stepsPerMinute = new JSlider(JSlider.HORIZONTAL, STEPS_MIN,
				STEPS_MAX, STEPS_INIT);
		stepsPerMinute.setBorder(BorderFactory
				.createTitledBorder("Steps per Minute"));
		stepsPerMinute.setMajorTickSpacing(MAJOR_TICK_SPACING);
		stepsPerMinute.setMinorTickSpacing(MINOR_TICK_SPACING);
		stepsPerMinute.setPaintTicks(true);
		stepsPerMinute.setPaintLabels(true);
		stepsPerMinute.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				JSlider slider = (JSlider) e.getSource();
				int value = (1000 * 60) / slider.getValue();
				runtimeController.setSpeed(value);
			}
		});
		return stepsPerMinute;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(rewind)) {
			runtimeController.rewind();
		}
		if (e.getSource().equals(rewindOneStep)) {
			runtimeController.rewindOneStep();
		}
		if (e.getSource().equals(pause)) {
			runtimeController.stop();
		}
		if (e.getSource().equals(playOneStep)) {
			runtimeController.playOneStep();
		}
		if (e.getSource().equals(play)) {
			runtimeController.play();
		}
	}

	/** Returns an ImageIcon, or null if the path was invalid. */
	protected ImageIcon createImageIcon(String path, String description) {
		java.net.URL imgURL = getClass().getResource(path);
		if (imgURL != null) {
			return new ImageIcon(imgURL, description);
		} else {
			System.err.println("Couldn't find file: " + path);
			return null;
		}
	}
}
